import sys
import linecache
import os
import time

class tracer:

   def __init__(self):
      self._level = 0
      self._startTime = int(time.time())
      self._curTime = [0,0] # First component is seconds, second increments if commands are run within the same second
      self._onlyLocalFiles = True # Turn on/off to show all debuging or only stuff for local files
      self._dirList = os.listdir('.')

   # Based off of code from: http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html
   def traceit(self, frame, event, arg):

      # Gather information
      lineno = frame.f_lineno
      filename = frame.f_globals["__file__"]
      if (filename.endswith(".pyc") or
         filename.endswith(".pyo")):
         filename = filename[:-1]
      name = frame.f_globals["__name__"]
      line = linecache.getline(filename, lineno)

      # If we want local files, show only local files
      if self._onlyLocalFiles is True:
         fullName = name + ".py"
         if fullName not in self._dirList:
            return self.traceit

      # Take care of the indention
      if event is "return":
         self._level-=1
      if event is "call":
         self._level+=1
         trace = "+"*self._level
      else:
         trace = "|"*self._level+ "-"

      # Calculate the time
      curTime = abs(int(time.time() - self._startTime))
      if self._curTime[0] is curTime:
         self._curTime[1]+=1
      else:
         self._curTime[0] = curTime
         self._curTime[1] = 0
      

      # Now produce the string!
      trace = "%s[%s.%s]%s:%s:%s" % (trace , self._curTime[0], self._curTime[1], str(name) , str(lineno) , line.rstrip())

      print trace # Now show the trace!

      return self.traceit # This is needed so settrace can call traceit again the next time

   def settrace(self):
      sys.settrace(self.traceit)

